home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / lfs / lfsLoad.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  9.4 KB  |  331 lines

  1. /* 
  2.  * lfsLoad.c --
  3.  *
  4.  *    Code to handle the loading, checkpoint, and detaching of LFS file
  5.  *    system.
  6.  *
  7.  * Copyright 1989 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/lfs/lfsLoad.c,v 1.10 91/12/17 17:33:48 jhh Exp $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include <sprite.h>
  22. #include <lfsInt.h>
  23. #include <stdlib.h>
  24. #include <rpc.h>
  25.  
  26. #include <string.h>
  27. #include <lfs.h>
  28.  
  29. static Fsdm_DomainOps lfsDomainOps = {
  30.     Lfs_AttachDisk,
  31.     Lfs_DetachDisk,
  32.     Lfs_DomainWriteBack,
  33.     Lfs_RereadSummaryInfo,
  34.     Lfs_DomainInfo,
  35.     Lfs_BlockAllocate,
  36.     Lfs_GetNewFileNumber,
  37.     Lfs_FreeFileNumber,
  38.     Lfs_FileDescInit,
  39.     Lfs_FileDescFetch,
  40.     Lfs_FileDescStore,
  41.     Lfs_FileBlockRead,
  42.     Lfs_FileBlockWrite,
  43.     Lfs_FileTrunc,
  44.     Lfs_DirOpStart,
  45.     Lfs_DirOpEnd
  46. };
  47.  
  48.  
  49.  
  50. /*
  51.  *----------------------------------------------------------------------
  52.  *
  53.  * LfsLoadFileSystem --
  54.  *
  55.  *    Load the checkpointed state of a file system and call the LFS
  56.  *    module attach routines to initialize a file system.
  57.  *
  58.  * Results:
  59.  *    SUCCESS if the file system was successfully loaded. 
  60.  *
  61.  * Side effects:
  62.  *    None.
  63.  *
  64.  *----------------------------------------------------------------------
  65.  */
  66.  
  67. ReturnStatus
  68. LfsLoadFileSystem(lfsPtr, flags)
  69.     Lfs        *lfsPtr;    /* File system to load checkpoint state. */
  70.     int      flags;    
  71. {
  72.     ReturnStatus    status;
  73.     LfsCheckPointHdr    checkPointHdr[2], *checkPointHdrPtr;
  74.     LfsCheckPointTrailer *trailerPtr;
  75.     LfsDiskAddr        diskAddr;
  76.     int            choosenOne, maxSize;
  77.     char        *checkPointPtr;
  78.     int            checkPointSize;
  79.  
  80.     Sync_LockInitDynamic(&(lfsPtr->checkPointLock), "LfsCheckpointLock");
  81.     /*
  82.      * Examine the two checkpoint areas to locate the checkpoint area with the
  83.      * newest timestamp.
  84.      */
  85.     LfsOffsetToDiskAddr(lfsPtr->superBlock.hdr.checkPointOffset[0],
  86.         &diskAddr);
  87.     status = LfsReadBytes(lfsPtr, diskAddr, sizeof(LfsCheckPointHdr),
  88.              (char *) (checkPointHdr+0));
  89.     if (status != SUCCESS) {
  90.     LfsError(lfsPtr, status, "Can't read checkpoint header #0");
  91.     return status;
  92.     }
  93.     LfsOffsetToDiskAddr(lfsPtr->superBlock.hdr.checkPointOffset[1],
  94.         &diskAddr);
  95.     status = LfsReadBytes(lfsPtr, diskAddr, sizeof(LfsCheckPointHdr), 
  96.         (char *) (checkPointHdr+1));
  97.     if (status != SUCCESS) {
  98.     LfsError(lfsPtr, status, "Can't read checkpoint header #1");
  99.     return status;
  100.     }
  101.     choosenOne = (checkPointHdr[0].timestamp<checkPointHdr[1].timestamp) ? 1 : 0;
  102.  
  103.     /*
  104.      * Read in the entire checkpoint region into a buffer.
  105.      */
  106.     maxSize = LfsBlocksToBytes(lfsPtr, 
  107.                 (lfsPtr->superBlock.hdr.maxCheckPointBlocks));
  108.     checkPointPtr = malloc(maxSize);
  109.  
  110. again:
  111.     LfsOffsetToDiskAddr(lfsPtr->superBlock.hdr.checkPointOffset[choosenOne],
  112.         &diskAddr);
  113.     status = LfsReadBytes(lfsPtr, diskAddr,  maxSize, checkPointPtr);
  114.     if (status != SUCCESS) {
  115.     free((char *) checkPointPtr);
  116.     LfsError(lfsPtr, status, "Can't read checkpoint region");
  117.     return status;
  118.     }
  119.     /*
  120.      * Verify checksum checkpoint region here.
  121.      */
  122.     checkPointHdrPtr = (LfsCheckPointHdr *) checkPointPtr;
  123.     trailerPtr = (LfsCheckPointTrailer *) 
  124.         (checkPointPtr + checkPointHdrPtr->size - 
  125.                 sizeof(LfsCheckPointTrailer));
  126.  
  127.     if (checkPointHdrPtr->timestamp != trailerPtr->timestamp) {
  128.     LfsError(lfsPtr, SUCCESS, "Bad checkpoint timestamps");
  129.     choosenOne = !choosenOne;
  130.     goto again;
  131.     }
  132.  
  133.     /*
  134.      * Install the domain if we can. 
  135.      */
  136.     status = Fsdm_InstallDomain(checkPointHdrPtr->domainNumber, 
  137.                 checkPointHdrPtr->serverID, lfsPtr->name, 
  138.                 flags, &(lfsPtr->domainPtr));
  139.     if (status != SUCCESS) {
  140.     free((char *) checkPointHdrPtr);
  141.     return (status);
  142.     }
  143.     lfsPtr->domainPtr->backendPtr = LfsCacheBackendInit(lfsPtr);
  144.     lfsPtr->domainPtr->domainOpsPtr = &lfsDomainOps;
  145.     lfsPtr->domainPtr->clientData = (ClientData) lfsPtr;
  146.  
  147.     /*
  148.      * Read in the current stats structure.
  149.      */
  150.     { 
  151.     Lfs_StatsVersion1 *statsPtr = (Lfs_StatsVersion1 *)(trailerPtr + 1);
  152.     if (statsPtr->version != 1) {
  153.         printf("LfsLoad: Bad stats version number %d\n", statsPtr->version);
  154.     }
  155.     bcopy ((char *) statsPtr, (char *) &lfsPtr->stats, 
  156.         sizeof(lfsPtr->stats));
  157.     }
  158.     checkPointPtr = checkPointPtr + sizeof(LfsCheckPointHdr);
  159.     checkPointSize =  ((char *)trailerPtr) - checkPointPtr;
  160.     /*
  161.      * Process the checkpoint for each region by  calling segment attach
  162.      * procedures for the modules doing segment I/O.
  163.      */
  164.  
  165.     status = LfsSegAttach(lfsPtr, checkPointPtr, checkPointSize);
  166.  
  167.     if (status != SUCCESS) {
  168.     free((char *) checkPointHdrPtr);
  169.     return status;
  170.     }
  171.  
  172.     /*
  173.      * Setup checkPoint data structure for next checkpoint operation. We use
  174.      * the buffer we allocated and set the nextRegion to be the one we
  175.      * didn't load from. Also set the timestamp into the future.
  176.      */
  177.     lfsPtr->checkPoint.timestamp = checkPointHdrPtr->timestamp+1;
  178.     lfsPtr->checkPoint.nextArea = !choosenOne;
  179.     lfsPtr->checkPoint.buffer = (char *) checkPointHdrPtr;
  180.     lfsPtr->checkPoint.maxSize = maxSize;
  181.  
  182.     /*
  183.      * Fill in the checkPointHdrPtr will the fields that don't change
  184.      * between checkpoints.
  185.      */
  186.     checkPointHdrPtr->timestamp = lfsPtr->checkPoint.timestamp;
  187.     checkPointHdrPtr->size = 0;
  188.     checkPointHdrPtr->version = 1;
  189.     checkPointHdrPtr->domainNumber = lfsPtr->domainPtr->domainNumber;
  190.     checkPointHdrPtr->attachSeconds = Fsutil_TimeInSeconds();
  191.     checkPointHdrPtr->detachSeconds = checkPointHdrPtr->attachSeconds;
  192.     checkPointHdrPtr->serverID = rpc_SpriteID;
  193.  
  194.     return status;
  195. }
  196.  
  197. /*
  198.  *----------------------------------------------------------------------
  199.  *
  200.  * LfsDetachFileSystem --
  201.  *
  202.  *    Detach a file system.
  203.  *
  204.  * Results:
  205.  *    SUCCESS if the file system was successfully detach. 
  206.  *
  207.  * Side effects:
  208.  *    None.
  209.  *
  210.  *----------------------------------------------------------------------
  211.  */
  212.  
  213. ReturnStatus
  214. LfsDetachFileSystem(lfsPtr)
  215.     Lfs        *lfsPtr;    /* File system to load checkpoint state. */
  216. {
  217.     ReturnStatus    status;
  218.  
  219.  
  220.     (*lfsPtr->checkpointIntervalPtr) = 0;  /* Stop the timer checkpointer. */
  221.  
  222.     status = LfsCheckPointFileSystem(lfsPtr, LFS_CHECKPOINT_DETACH);
  223.  
  224.     status = LfsSegDetach(lfsPtr);
  225.  
  226.     free(lfsPtr->checkPoint.buffer);
  227.     return status;
  228. }
  229. #define    LOCKPTR &lfsPtr->checkPointLock
  230.  
  231.  
  232. /*
  233.  *----------------------------------------------------------------------
  234.  *
  235.  * LfsCheckPointFileSystem --
  236.  *
  237.  *    Checkpoint the state of a file system by calling the LFS
  238.  *    module attach routines.
  239.  *
  240.  * Results:
  241.  *    SUCCESS if the file system was successfully checkpointed. 
  242.  *
  243.  * Side effects:
  244.  *    None.
  245.  *
  246.  *----------------------------------------------------------------------
  247.  */
  248.  
  249. ReturnStatus
  250. LfsCheckPointFileSystem(lfsPtr, flags)
  251.     Lfs        *lfsPtr;    /* File system to be checkpointed. */
  252.     int flags;        /* Flags for checkpoint. */
  253. {
  254.     LfsCheckPointHdr    *checkPointHdrPtr;
  255.     int            size, blocks, bytes;
  256.     LfsCheckPointTrailer *trailerPtr;
  257.     LfsDiskAddr        diskAddr;
  258.     ReturnStatus    status;
  259.     char        *bufferPtr;
  260.  
  261.     bufferPtr = lfsPtr->checkPoint.buffer;
  262.     checkPointHdrPtr = (LfsCheckPointHdr *) bufferPtr;
  263.     if (flags & LFS_CHECKPOINT_CLEANER) { 
  264.     /* 
  265.      * The cleaner uses it own checkpoint buffer. Allocate it 
  266.      * and initialized the LfsCheckPointHdr with the values that
  267.      * don't change. 
  268.      */
  269.     bufferPtr = malloc(lfsPtr->checkPoint.maxSize);
  270.     bcopy((char *) checkPointHdrPtr, bufferPtr, 
  271.         sizeof(LfsCheckPointHdr));
  272.     checkPointHdrPtr = (LfsCheckPointHdr *) bufferPtr;
  273.  
  274.     }  
  275.  
  276.  
  277.     status = LfsSegCheckPoint(lfsPtr, flags, (char *)(checkPointHdrPtr+1),
  278.                 &size);
  279.     if ((status != SUCCESS) || (size < 0)) {
  280.     if (bufferPtr != lfsPtr->checkPoint.buffer) {
  281.         free(bufferPtr);
  282.     }
  283.     return status;
  284.     }
  285.     LOCK_MONITOR;
  286.     /*
  287.      * Fill in check point header and trailer.
  288.      */
  289.     checkPointHdrPtr->timestamp = LfsGetCurrentTimestamp(lfsPtr);
  290.     checkPointHdrPtr->size = size + sizeof(LfsCheckPointHdr) + 
  291.              sizeof(LfsCheckPointTrailer);
  292.     checkPointHdrPtr->version = 1;
  293.     checkPointHdrPtr->detachSeconds = Fsutil_TimeInSeconds();
  294.     trailerPtr = (LfsCheckPointTrailer *) 
  295.         (bufferPtr + size + sizeof(LfsCheckPointHdr));
  296.     trailerPtr->timestamp = checkPointHdrPtr->timestamp;
  297.     trailerPtr->checkSum = 0;
  298.  
  299.     /*
  300.      * Append the stats to the checkpoint regions.
  301.      */
  302.     bytes = checkPointHdrPtr->size + sizeof(Lfs_Stats);
  303.     blocks = LfsBytesToBlocks(lfsPtr, bytes);
  304.     LFS_STATS_ADD(lfsPtr->stats.checkpoint.totalBlocks, blocks);
  305.     LFS_STATS_ADD(lfsPtr->stats.checkpoint.totalBytes, bytes);
  306.     bcopy ((char *) &lfsPtr->stats, (char *) (trailerPtr + 1), 
  307.         sizeof(lfsPtr->stats));
  308.     LfsOffsetToDiskAddr(
  309.     lfsPtr->superBlock.hdr.checkPointOffset[lfsPtr->checkPoint.nextArea],
  310.         &diskAddr);
  311.     status = LfsWriteBytes(lfsPtr, diskAddr, 
  312.     LfsBlocksToBytes(lfsPtr, blocks), (char *) checkPointHdrPtr);
  313.     if (status == SUCCESS) {
  314.     /*
  315.      * Set the file system up to use the other checkpoint buffer next time.
  316.      */
  317.     lfsPtr->checkPoint.nextArea = !lfsPtr->checkPoint.nextArea;
  318.     } else {
  319.     UNLOCK_MONITOR;
  320.     LfsError(lfsPtr, status, "Can't write checkpoint region\n");
  321.     LOCK_MONITOR;
  322.     }
  323.     UNLOCK_MONITOR;
  324.     LfsSegCheckPointDone(lfsPtr, flags);
  325.     if (bufferPtr != lfsPtr->checkPoint.buffer) {
  326.     free(bufferPtr);
  327.     }
  328.     return status;
  329. }
  330.  
  331.